package cn.compose.online.util;

import cn.compose.online.constant.GroovyConstants;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

public class GroovyGenerateUtils {

    public static String defaultDef = "    def result = ";
    public static String defaultReturn = "\n    return result;\n";
    public static String defaultRunReturn = "\n    return result.toString();\n\n";
    public static String classGeet = "class RunCodeClass{\n" +
            "    public String execute(Map<String, String[]> map) {\n";
    public static String classBrace = "  }\n}";

    public static String ifParse = "    if ( %s ) {\n" +
            "        result = %s;\n" +
            "    }\n";
    public static Map<String,String> strMap=new HashMap<>();
    static {
        strMap.put("+","+");
        strMap.put("-","-");
        strMap.put("*","*");
        strMap.put("/","/");
        strMap.put(">",">");
        strMap.put("=","=");
        strMap.put("?","?");
        strMap.put(":",":");
        strMap.put("(","(");
        strMap.put(")",")");
    }

    public static String groovyGenerate(String variable,JSONObject ifData,String type) {
        JSONArray array = JSONUtil.parseArray(ifData.get("ifData"));
        String defaultData = ifData.getStr("defaultData");
        AtomicReference<String> result = new AtomicReference<>("");
        if(GroovyConstants.typeRun.equals(type)){
            result.set(classGeet);
        }
        result.set(result +ParamsParseUtils.getDefStr(variable)+defaultDef+ (Strings.isNullOrEmpty(defaultData)?"null;\n":defaultData+";\n"));

        for (Object entry : array) {
            String ifValue = "";
            String resultValue = "";
            JSONObject json = JSONUtil.parseObj(entry);
            Iterator it = json.keySet().iterator();
            while(it.hasNext()){
                String key = (String) it.next();
                if(key.contains("ifInput")){
                    ifValue =json.getStr(key);
                }else if(key.contains("resultInput")){
                    resultValue =json.getStr(key);
//                    boolean flag=resultValue.matches("[0-9]+");
//                    Boolean isNotStr = hasStrInValue(resultValue);
//                    if(!isNotStr&&!flag){
//                        resultValue = '"'+resultValue+'"';
//                    }

                }
            }
            result.set(result + String.format(ifParse, ifValue, resultValue));

        }
        if(GroovyConstants.typeGenerate.equals(type)){
            result.set(result+defaultReturn);
            return result.get();
        }
        result.set(result+defaultRunReturn+classBrace);

        return result.get();
    }

    public static Boolean hasStrInValue(String str){
        AtomicReference<Boolean> flag = new AtomicReference<>(false);
        strMap.entrySet().forEach(entry->{
            String key=entry.getKey();
            if(str.indexOf(key)!=-1){
                flag.set(true);
            }
        });
        return flag.get();
    }


    public static String getInputParamsName(String variable){
        List<String> result=new LinkedList<>();
        Map<String,String> params=ParamsParseUtils.getDefMap(variable);
        if(CollectionUtils.isEmpty(params)){
            return "";
        }

        params.entrySet().forEach(entry->{
            String value=entry.getValue();
            if(value.contains("N_")||value.contains("$lastState")){
                result.add(entry.getKey());
            }
        });
        return StringUtils.join(result.toArray(),",");
    }

    public static String getInputParams(String variable){
        List<String> result=new ArrayList<>();
        Map<String,String> params=ParamsParseUtils.getDefMap(variable);
        if(CollectionUtils.isEmpty(params)){
            return "";
        }

        params.entrySet().forEach(entry->{
            String value=entry.getValue();
            if(value.contains("N_")||value.contains("$lastState")){
                result.add(value);
            }
        });
        return StringUtils.join(result.toArray(),",");
    }
}
